package com.ht.api.call.func.impl.kf;

import com.ht.api.bean.AjaxResult;
import com.ht.api.bean.LoginBean;
import com.ht.api.call.func.IFunctionCall;
import com.ht.api.db.Db;
import com.ht.api.db.Entity;
import com.ht.api.db.exception.HtException;
import com.ht.api.db.util.HtUtil;
import com.ht.api.open.OpenUtil;
import com.ht.api.service.OfficialService;
import com.ht.api.service.WwxService;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

/**
 * 客服发送消息
 * @author asq
 * @createTime 2025年3月9日 09:11:00
 */
public class KfSendMessageFunctionCall implements IFunctionCall {
	/** 接口：发送企业微信客服消息 */
	private static final long API_ID_SEND = 1891365068554244096L;
	/** 接口：发送公众号客服消息 */
	private static final long API_ID_SEND_OFFICIAL = 1909505519941455872L;

	@Override
	public String getName() {
		return "客服发送消息";
	}

	@Override
	public JSONObject execute(LoginBean me, JSONObject param, AjaxResult result) {

		// 判断会话是否已过期
		String sessionId = param.getStr("session_id");
		Entity kfSession = Db.createSqlParser("kf_session")
				.where("main_id", sessionId)
				.findOne(me.getDataSource());
		if (kfSession == null) {
			throw new HtException("会话不存在，无法发送消息！");
		}
		if (kfSession.getInt("status") == 2) {
			throw new HtException("会话已过期，不能发送消息！");
		}
		if (kfSession.getInt("session_msg_cnt") >= 5) {
			throw new HtException("已发送5条消息，需要用户主动发送消息后才能再次发送消息！");
		}

		// 调用企微接口
		JSONObject obj = null;
		Integer type = kfSession.getInt("type");
		if (type == 0) {
			// 向企微发送消息
			obj = sendMessageToApi(kfSession, param);
		} else {
			// 向公众号发送消息
			obj = sendMessageToApiByOfficial(kfSession, param);
		}
		
		if (obj.getInt("errcode") == 0) {
			String msgId = obj.getStr(type == 0 ? "msgid" : "MsgId");
			return addToDb(me, HtUtil.revertJson(param), msgId, type, kfSession);
		} else {
			throw new HtException("企微接口返回错误：" + obj.getStr("errmsg"));
		}

	}

	private JSONObject sendMessageToApi (Entity kfSession, JSONObject param) {
		String appId = kfSession.getStr("appid");
		JSONObject apiParam = JSONUtil.createObj();
		apiParam.set("touser", kfSession.getStr("openid"));
		apiParam.set("open_kfid", kfSession.getStr("open_kfid"));

		JSONObject content = JSONUtil.parseObj(param.get("content"));
		String msgtype = content.getStr("msgtype");
		String attachUrl = content.getJSONObject(msgtype).getStr("attach_url");
		if (msgtype.equals("image")) {
			String mediaId = WwxService.getTempImageMediaId(appId, attachUrl);
			content.putOpt(msgtype + ".media_id", mediaId);
		} else if (msgtype.equals("voice")) {
			String mediaId = WwxService.getTempVoiceMediaId(appId, attachUrl);
			content.putOpt(msgtype + ".media_id", mediaId);
		} else if (msgtype.equals("video")) {
			String mediaId = WwxService.getTempVideoMediaId(appId, attachUrl);
			content.putOpt(msgtype + ".media_id", mediaId);
		} else if (msgtype.equals("file")) {
			String mediaId = WwxService.getTempFileMediaId(appId, attachUrl);
			content.putOpt(msgtype + ".media_id", mediaId);
		} else if (msgtype.equals("link")) {
			String mediaId = WwxService.getTempImageMediaId(appId, attachUrl);
			content.putOpt(msgtype + ".thumb_media_id", mediaId);
		} else if (msgtype.equals("miniprogram")) {
			String mediaId = WwxService.getTempImageMediaId(appId, attachUrl);
			content.putOpt(msgtype + ".thumb_media_id", mediaId);
		}
		content.getJSONObject(msgtype).remove("attach_url");
		apiParam.putAll(content);

		String str = OpenUtil.callByNoAssemble(appId, API_ID_SEND, apiParam);

		// 如果企微接口调用成功，则操作本地数据库
		JSONObject obj = JSONUtil.parseObj(str);

		return obj;
	}

	/**
	 * 发送公众号客服消息
	 * @param param
	 * @return
	 */
	private JSONObject sendMessageToApiByOfficial (Entity kfSession, JSONObject param) {
		String appId = kfSession.getStr("appid");
		JSONObject apiParam = JSONUtil.createObj();
		apiParam.set("touser", kfSession.getStr("openid"));

		JSONObject content = JSONUtil.parseObj(param.get("content"));
		String msgtype = content.getStr("msgtype");
		String attachUrl = content.getJSONObject(msgtype).getStr("attach_url");
		if (msgtype.equals("image")) {
			String mediaId = OfficialService.getTempImageMediaId(appId, attachUrl);
			content.putOpt(msgtype + ".media_id", mediaId);
		} else if (msgtype.equals("voice")) {
			String mediaId = OfficialService.getTempVoiceMediaId(appId, attachUrl);
			content.putOpt(msgtype + ".media_id", mediaId);
		} else if (msgtype.equals("video")) {
			String mediaId = OfficialService.getTempVideoMediaId(appId, attachUrl);
			content.putOpt(msgtype + ".media_id", mediaId);
		} else if (msgtype.equals("file")) {
			String mediaId = OfficialService.getTempFileMediaId(appId, attachUrl);
			content.putOpt(msgtype + ".media_id", mediaId);
		} else if (msgtype.equals("link")) {
			String mediaId = OfficialService.getTempImageMediaId(appId, attachUrl);
			content.putOpt(msgtype + ".thumb_media_id", mediaId);
		} else if (msgtype.equals("miniprogram")) {
			String mediaId = OfficialService.getTempImageMediaId(appId, attachUrl);
			content.putOpt(msgtype + ".thumb_media_id", mediaId);
		}
		content.getJSONObject(msgtype).remove("attach_url");
		apiParam.putAll(content);

		String str = OpenUtil.callByNoAssemble(appId, API_ID_SEND_OFFICIAL, apiParam);

		// 如果企微接口调用成功，则操作本地数据库
		JSONObject obj = JSONUtil.parseObj(str);

		return obj;
	}

	/**
	 * 新增到kf_message
	 * @param param 前端参数
	 */
	private Entity addToDb(LoginBean me, JSONObject param, String msgId, int type, Entity kfSession) {
		// 是否是企微消息
		boolean isWwx = type == 0;

		Entity kfMessage = Db.createEntity("kf_message");
		kfMessage.set("session_id", kfSession.getMainId());
		kfMessage.set("msgid", msgId);
		kfMessage.set("open_kfid", kfSession.getStr("open_kfid"));
		kfMessage.set("openid", kfSession.getStr("openid"));
		kfMessage.set("userid", me.getLoginIdStr());
		kfMessage.set("send_time", DateUtil.now());
		kfMessage.set("origin", 2);
		kfMessage.set("msgtype", param.getJSONObject("content").getStr("msgtype"));
		kfMessage.set("content", param.get("content"));
		kfMessage.set("appid", param.getStr("appid"));
		Db.insert(me.getDataSource(), kfMessage);

		Entity session = Entity.create("kf_session");
		session.setMainId(kfSession.getMainId());
		session.set("msg", WwxService.formatMsg(param.getJSONObject("content")));
		session.set("session_msg_cnt", 1);
		session.set("servicer_msg_cnt", 1);
		Db.insert(me.getDataSource(), session);
		
		// 更新会话与客服关联表kf_session_servicer_relation
		Entity kfSessionServicerRelationEntity = Db.createSqlParser("kf_session_servicer_relation")
				.where("session_id", session.getMainId())
				.order("start_time", "desc").limit(1).findOne(me.getDataSource());
		if (kfSessionServicerRelationEntity != null) {
			Entity kfSessionServicerRelation = Entity.create("kf_session_servicer_relation");
			kfSessionServicerRelation.setMainId(kfSessionServicerRelationEntity.getMainId());
			kfSessionServicerRelation.set("last_msg_time", DateUtil.now());
			kfSessionServicerRelation.set("servicer_msg_cnt", 1);
			Db.insert(me.getDataSource(), kfSessionServicerRelation);
		}

		return kfMessage;
	}
	
}
